/**
 * 文件名：@AbstractRequestBodyInterceptor.java <br/>
 * 包名：cn.efunbox.afw.web.mvc.interceptor <br/>
 * 项目名：afw-web <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.web.mvc.interceptor;

import java.io.BufferedReader;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import cn.efunbox.afw.web.util.AfwWebConstant;

/**
 * 类名：AbstractRequestBodyInterceptor  <br />
 *
 * 功能：请求体处理
 *
 * @author xtwin <br />
 * 创建时间：2016年7月25日 下午1:46:58  <br />
 * @version 2016年7月25日
 */
public abstract class AbstractRequestBodyInterceptor extends HandlerInterceptorAdapter {
	
	// 日志记录器
	private static final Logger logger = LoggerFactory.getLogger(AbstractRequestBodyInterceptor.class);
	
	// 要进行检查的请求头
	protected String checkHeader = "content-type";
	
	// 可以接受的值
	protected String acceptPattern = "application/json.*";
	
	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2016年7月25日 下午1:47:23<br/>
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @return
	 * @throws Exception <br/>
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// 不需要处理，跳过
		if (! accept(request, response, handler)) {
			return true;
		}
		
		// 读取数据体
		String body = readBody(request, response, handler);
		
		// 记录日志
		logger.debug("read body is. len: {}, body: {}", request.getContentLength(), body);
		
		if (null == body) {
			return true;
		}
		
		// 解析body
		Object data = parseBody(body, request, response, handler);
		
		logger.debug("parse body is : {}", data);
		
		// 保存到request
		request.setAttribute(AfwWebConstant.KEY_REQUEST_BODY, data);
		
		return true;
	}
	
	/**
	 * 功能：解析body内容 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年7月25日 下午2:00:26 <br/>
	 */
	protected abstract Object parseBody(String body, HttpServletRequest request, HttpServletResponse response, Object handler);
	
	/**
	 * 功能：读取数据体 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年7月25日 下午1:50:04 <br/>
	 */
	protected String readBody(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		StringBuilder sb = new StringBuilder();
		try (BufferedReader br = request.getReader()) {
			while (true) {
				String line = br.readLine();
				
				if (null == line) {
					break;
				}
				
				sb.append(line);
			}
		} catch (Exception e) {
			logger.warn("read fail with error : " + String.valueOf(e));
		}
		
		return sb.length() != 0 ? sb.toString() : null;
	}
	
	/**
	 * 功能：检查是否需要处理，默认检查请求头 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年7月25日 下午1:48:35 <br/>
	 */
	protected boolean accept(HttpServletRequest request, HttpServletResponse response, Object handler) {
		String value = request.getHeader(checkHeader);
		
		return null != value && value.matches(acceptPattern);
	}

	/**
	 * @version 2016年7月25日-下午2:09:22
	 */
	public void setCheckHeader(String checkHeader) {
		this.checkHeader = checkHeader;
	}

	/**
	 * @version 2016年7月25日-下午2:09:22
	 */
	public void setAcceptPattern(String acceptPattern) {
		this.acceptPattern = acceptPattern;
	}
}